﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlayerTest.Player.Event;
using System.Diagnostics;
using PlayerTest.Player.Handler;
using PlayerTest.CustomControls;
using PlayerTest.Player.Data;

namespace PlayerTest.Player.Controller
{
    class Controller
    {
        private bool isOpened = false;
        public bool Opened
        {
            get { return isOpened; }
        }
        #region Event Sending
        public event ControlEventHandler EventHandler;
        /// <summary>
        /// WPF Window에 메시지 전송
        /// </summary>
        /// <param name="arg"></param>
        private void SendControlEvent(ControlEventArgs arg)
        {
            // 연결된 모든 함수에 이벤트 전송
            ControlEventHandler handler = EventHandler;
            if (handler != null) handler(this, arg);
        }
        #endregion

        #region CorePlayer
        // Player Control
        private CorePlayer player;
        private System.Windows.Forms.Panel panel;

        public bool Open(string path)
        {
            // 이전 학습정보가 있다면 저장
            SaveStudyInfo();
            if (player.Open(path))
            {
                isOpened = true;
            }
            else
                isOpened = false;
            //SendPlayerEvent(new PlayerEventArgs(PlayerEventArgs.eventtype.PLAY));

            return isOpened;
        }
        public void Play() { player.Play(); }
        public void Pause() { player.Pause(); }
        public void Resize() { player.Resize(); }
        public void Stop() { player.Stop(); }
        public void Move() { /*player.Move();*/ }
        public void Capture() { player.FrameCapture( video.VideoID); }
        public void RecordStart() { player.RecordStart(); }
        public void RecordEnd() { player.RecordEnd(); }
        public string SectionStart()
        {
            // 시작위치 썸네일 생성
            player.FrameCapture( video.VideoID);

            // 시작위치 설정
            player.SectionStart();

            return TextTime(player.SectionStartTime);
        }
        public string SectionEnd()
        {
            player.SectionEnd();
            double start = player.SectionStartTime;
            double end = player.SectionEndTime;
            if (start < end)
            {
                // StudyInfo에 Section 추가
                studyHandler.InsertMySection(new InfoSection(start, end, player.RecentThumbFile));

                // 반복구간 정보 업데이트
                SendControlEvent( new ControlEventArgs(ControlEventArgs.eventtype.UPDATESECTION) );

                // 반복 시작!
                player.RepeatStart(start, end);
            }
            return TextTime(player.SectionEndTime);
        }
        public void SectionRelease()
        {
            player.RepeatRelease();
        }
        public void Repeat(double start, double end)
        {
            player.RepeatStart( start, end );
        }

        private string TextTime(double time)
        {
            int pos = (int)time;
            int hour = pos / 3600;
            int minute = pos / 60;
            int sec = pos % 60;

            return string.Format("{0}:{1}:{2}", hour.ToString("D2"), minute.ToString("D2"), sec.ToString("D2"));
        }

        public void SetVolume(double vol)
        {
            player.SetVolume(vol);
        }
        /// <summary>
        /// 재생 위치를 변경합니다.
        /// </summary>
        /// <param name="pos"></param>
        public void SetPosition(double pos)
        {
            player.SetPosition(pos);
            subtitle.SubtitleMonitoringMove();
        }

        public double GetPosition()
        {
            return player.CurrentPosition;
        }

        /// <summary>
        /// Player Event 처리
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="arg"></param>
        private void OnPlayerEvent(object sender, PlayerEventArgs arg)
        {
            switch (arg.EventType)
            {
                case PlayerEventArgs.eventtype.VIDEOINFO:
                    video.GetVideoID(arg.FileSize, arg.PlayTime);
                    ControlEventArgs con_arg = new ControlEventArgs(ControlEventArgs.eventtype.MAXPOS);
                    con_arg.IntValue = arg.PlayTime;

                    // Main Window에 메시지 전송
                    SendControlEvent(con_arg);
                    break;

                case PlayerEventArgs.eventtype.VOLUME:
                    ControlEventArgs vol_arg = new ControlEventArgs(ControlEventArgs.eventtype.VOLUME);
                    vol_arg.DoubleValue = arg.Volume;

                    // Main Window에 메시지 전송
                    SendControlEvent(vol_arg);
                    break;

                case PlayerEventArgs.eventtype.RENDER:
                    //player.BlendSubtitleText();
                    break;

                case PlayerEventArgs.eventtype.PLAYSTART:
                    // 자막 모니터링 시작
                    //subtitle.SubtitleMonitoringStart();
                    break;

                case PlayerEventArgs.eventtype.PLAYPAUSE:
                    // 자막 모니터링 일시정지
                    subtitle.SubtitleMonitoringPause();
                    break;

                case PlayerEventArgs.eventtype.PLAYSTOP:
                    subtitle.SubtitleMonitoringStop();
                    // 자막 모니터링 정지
                    break;

                case PlayerEventArgs.eventtype.REPEAT:
                    // 반복구간 시작점으로 돌아옴. 자막 새로고침
                    subtitle.SubtitleMonitoringStop();
                    subtitle.SubtitleMonitoringStart();
                    break;
            }
        }
        #endregion

        #region Subtitle Handler
        private SubtitleHandler subtitle;

        public PlayerTest.CorePlayer.SubType SubtitleType
        {
            get { return player.SubtitleType; }
            set
            {
                // 스레드 다시 시작
                subtitle.SubtitleMonitoringStop();
                subtitle.SubtitleMonitoringStart(value);

                // player 자막 타입 설정
                player.SubtitleType = value;
            }
        }
        // Subtitle Event 처리
        private void OnSubtitleEvent(object sender, SubtitleEventArgs arg)
        {
            switch (arg.EventType)
            {
                case SubtitleEventArgs.eventtype.MOVE:
                    player.SetPosition(arg.Position);
                    break;

                case SubtitleEventArgs.eventtype.PARSEFINISH:
                    if (arg.Result)
                    {
                        // 성공했다면 출력
                        SendControlEvent(new ControlEventArgs(ControlEventArgs.eventtype.UPDATESCRIPT));
                        System.IO.File.Delete("temp.smi");

                        // 자막 모니터링 시작
                        subtitle.SubtitleMonitoringStart(CorePlayer.SubType.KRCC);
                    }
                    else
                    {
                        SendControlEvent(new ControlEventArgs(ControlEventArgs.eventtype.SUBOPENERROR));
                    }
                    break;
            }
        }

        public void OpenSubtitle(string path)
        {
            subtitle.OpenSubtitle(path);
        }

        public List<SMIContent> KRCCScriptDictionary
        {
            get { return subtitle.DIC_KRCC; }
        }
        public List<SMIContent> ENCCScriptDictionary
        {
            get { return subtitle.DIC_ENCC; }
        }
        #endregion

        #region Video Handler
        private VideoHandler video;

        // Video Event 처리
        private void OnVideoEvent(object sender, VideoEventArgs arg)
        {
            switch (arg.EventType)
            {
                case VideoEventArgs.eventtype.ALERT:
                    if (arg.Message != null)
                        Trace.WriteLine(arg.Message);
                    break;

                case VideoEventArgs.eventtype.GETVIDEOID:
                    // VideoID를 얻어오면 바로 StudyInfo를 요청한다.
                    GetStudyInfo();           // 내 정보 & 추천 정보
                    break;
            }
        }

        #endregion

        #region User Handler
        private UserHandler user;

        // User Event 처리
        private void OnUserEvent(object sender, UserEventArgs arg)
        {
            ControlEventArgs con_arg = null;
            switch (arg.EventType)
            {
                case UserEventArgs.eventtype.LOGIN:
                    con_arg = new ControlEventArgs(ControlEventArgs.eventtype.LOGIN);
                    if (arg.Result)
                    {
                        // 로그인 성공시 ID 출력
                        con_arg.Result = true;
                        con_arg.Message = user.LoginID;
                    }
                    else
                    {
                        con_arg.Result = false;
                    }
                    SendControlEvent(con_arg);
                    break;

                case UserEventArgs.eventtype.ERROR:
                    con_arg = new ControlEventArgs(ControlEventArgs.eventtype.ERROR);
                    con_arg.Result = false;
                    con_arg.Message = arg.Message;
                    SendControlEvent(con_arg);
                    break;

                case UserEventArgs.eventtype.JOIN:
                    if (arg.Result)
                    {
                        // 가입 성공
                        con_arg = new ControlEventArgs(ControlEventArgs.eventtype.JOIN);
                        con_arg.Result = true;
                        con_arg.Message = arg.Message;
                        SendControlEvent(con_arg);
                    }
                    else
                    {
                        con_arg = new ControlEventArgs(ControlEventArgs.eventtype.JOIN);
                        con_arg.Result = false;
                        con_arg.Message = arg.Message;
                        SendControlEvent(con_arg);
                    }
                    break;
            }
        }

        public void Login(string id, string pw)
        {
            user.Login(id, pw);
        }
        public void Logout()
        {
            user.Logout();
        }
        public void Join( string email, string nick, string pw )
        {
            user.Join(email, nick, pw);
        }
        #endregion

        #region StudyInfo Handler
        private StudyInfoHandler studyHandler;
        public List<InfoSection> SectionDictionary
        {
            get { return studyHandler.MySection; }
        }
        public List<InfoWord> WordDictionary
        {
            get { return studyHandler.MyWord; }
        }
        public List<InfoSentence> SentenceDictionary
        {
            get { return studyHandler.MySentence; }
        }

        public List<InfoSection> RecommendSectionDictionary
        {
            get { return studyHandler.RecommendSection; }
        }
        public List<InfoWord> RecommendWordDictionary
        {
            get { return studyHandler.RecommendWord; }
        }
        public List<InfoSentence> RecommendSentenceDictionary
        {
            get { return studyHandler.RecommendSectence; }
        }

        // User Event 처리
        private void OnStudyInfoEvent(object sender, StudyInfoEventArgs arg)
        {
            ControlEventArgs con_arg = null;
            switch (arg.EventType)
            {
                case StudyInfoEventArgs.eventtype.DOWNFINISH:
                    SendControlEvent(new ControlEventArgs(ControlEventArgs.eventtype.UPDATESTUDYINFO));
                    break;
            }
        }

        public void GetStudyInfo()
        {
            int userID = user.UserID;
            int videoID = video.VideoID;

            if (userID > 0 && videoID > 0)
            {
                studyHandler.RequestMyStudyInfo(userID, videoID);
                studyHandler.RequestRecommendStudyInfo(userID, videoID);
                studyHandler.RequestImageDownload();
            }
        }

        public void SaveStudyInfo()
        {
            int userID = user.UserID;
            int videoID = video.VideoID;

            if (userID > 0 && videoID > 0)
            {
                studyHandler.SaveStudyInfo(userID, videoID);
            }
        }

        #endregion

        #region Common
        private IntPtr windowHandle = IntPtr.Zero;

        public Controller
            (
                System.Windows.Forms.Panel _panel
            )
        {
            panel = _panel;
            player = new CorePlayer(panel);
            video = new VideoHandler();
            subtitle = new SubtitleHandler();
            subtitle.player = player;
            user = new UserHandler();
            studyHandler = new StudyInfoHandler();

            player.EventHandler += new PlayerEventHandler(OnPlayerEvent);
            video.EventHandler += new VideoEventHandler(OnVideoEvent);
            subtitle.EventHandler += new SubtitleEventHandler(OnSubtitleEvent);
            user.EventHandler += new UserEventHandler(OnUserEvent);
            studyHandler.EventHandler += new StudyInfoEventHandler(OnStudyInfoEvent);
        }

        /// <summary>
        /// 자막 이벤트를 처리하기 위한 함수
        /// </summary>
        /// <param name="_handle"></param>
        public void SetWindowHandle(IntPtr _handle)
        {
            windowHandle = _handle;
            player.SetWindowHandle(windowHandle);
        }
        #endregion
    }
}
